using System;
using System.Diagnostics;
using System.Drawing;
using System.Drawing.Imaging;
using System.Runtime.InteropServices;
using System.IO;

namespace LarkShot
{
    public class ScreenshotCapture
    {
        [DllImport("user32.dll")]
        private static extern IntPtr GetWindowRect(IntPtr hWnd, ref Rectangle rect);

        [DllImport("user32.dll")]
        private static extern IntPtr GetClientRect(IntPtr hWnd, ref Rectangle rect);

        [DllImport("user32.dll")]
        private static extern IntPtr ClientToScreen(IntPtr hWnd, ref Point point);

        [DllImport("user32.dll")]
        private static extern IntPtr GetForegroundWindow();

        [DllImport("user32.dll")]
        private static extern int GetWindowText(IntPtr hWnd, System.Text.StringBuilder text, int count);

        [DllImport("user32.dll")]
        private static extern IntPtr FindWindow(string lpClassName, string lpWindowName);

        [DllImport("user32.dll")]
        private static extern bool IsWindowVisible(IntPtr hWnd);

        [DllImport("user32.dll")]
        private static extern bool PrintWindow(IntPtr hwnd, IntPtr hDC, uint nFlags);

        [DllImport("user32.dll")]
        private static extern IntPtr GetDC(IntPtr hWnd);

        [DllImport("user32.dll")]
        private static extern IntPtr ReleaseDC(IntPtr hWnd, IntPtr hDC);

        [DllImport("gdi32.dll")]
        private static extern bool BitBlt(IntPtr hdc, int nXDest, int nYDest, int nWidth, int nHeight, IntPtr hdcSrc, int nXSrc, int nYSrc, uint dwRop);

        [DllImport("user32.dll")]
        private static extern bool SetForegroundWindow(IntPtr hWnd);

        [DllImport("user32.dll")]
        private static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);

        [DllImport("user32.dll")]
        private static extern bool UpdateWindow(IntPtr hWnd);

        [DllImport("dwmapi.dll")]
        private static extern int DwmGetWindowAttribute(IntPtr hwnd, int dwAttribute, out Rectangle pvAttribute, int cbAttribute);

        private const int DWMWA_EXTENDED_FRAME_BOUNDS = 9;
        private const int SW_RESTORE = 9;

        public static IntPtr FindTargetWindow(string windowTitle)
        {
            Process[] processes = Process.GetProcessesByName(Path.GetFileNameWithoutExtension(windowTitle));
            
            foreach (var process in processes)
            {
                if (process.MainWindowHandle != IntPtr.Zero && IsWindowVisible(process.MainWindowHandle))
                {
                    return process.MainWindowHandle;
                }
            }
            return IntPtr.Zero;
        }

        public static Bitmap CaptureWindow(IntPtr windowHandle)
        {
            try
            {
                // 先尝试激活窗口确保其在前台
                SetForegroundWindow(windowHandle);
                ShowWindow(windowHandle, SW_RESTORE);
                UpdateWindow(windowHandle);
                
                // 给窗口一点时间来刷新
                System.Threading.Thread.Sleep(100);

                // 获取客户区大小和位置
                Rectangle clientRect = new Rectangle();
                GetClientRect(windowHandle, ref clientRect);
                
                // 将客户区坐标转换为屏幕坐标
                Point clientTopLeft = new Point(0, 0);
                ClientToScreen(windowHandle, ref clientTopLeft);
                
                // 构造客户区的屏幕坐标矩形
                Rectangle captureRect = new Rectangle(
                    clientTopLeft.X,
                    clientTopLeft.Y,
                    clientRect.Width,
                    clientRect.Height
                );

                int width = captureRect.Width;
                int height = captureRect.Height;

                if (width <= 0 || height <= 0)
                    return null;

                // 使用屏幕DC进行截图，只截取客户区内容
                Bitmap bitmap = new Bitmap(width, height);
                using (Graphics graphics = Graphics.FromImage(bitmap))
                {
                    IntPtr hdcDest = graphics.GetHdc();
                    IntPtr hdcSrc = GetDC(IntPtr.Zero); // 获取屏幕DC

                    try
                    {
                        // 从屏幕复制窗口客户区
                        const uint SRCCOPY = 0x00CC0020;
                        BitBlt(hdcDest, 0, 0, width, height, hdcSrc, captureRect.X, captureRect.Y, SRCCOPY);
                    }
                    finally
                    {
                        ReleaseDC(IntPtr.Zero, hdcSrc);
                        graphics.ReleaseHdc(hdcDest);
                    }
                }

                return bitmap;
            }
            catch (Exception ex)
            {
                System.Windows.MessageBox.Show($"截图失败: {ex.Message}", "错误");
                return null;
            }
        }

        public static Bitmap AutoCropBlackBorders(Bitmap originalBitmap)
        {
            try
            {
                // 使用 LockBits 来快速处理像素数据
                BitmapData bitmapData = originalBitmap.LockBits(
                    new Rectangle(0, 0, originalBitmap.Width, originalBitmap.Height),
                    ImageLockMode.ReadOnly,
                    PixelFormat.Format24bppRgb);

                int bytesPerPixel = 3;
                int stride = bitmapData.Stride;
                IntPtr ptr = bitmapData.Scan0;

                // 将数据复制到字节数组
                byte[] rgbValues = new byte[stride * originalBitmap.Height];
                System.Runtime.InteropServices.Marshal.Copy(ptr, rgbValues, 0, rgbValues.Length);

                originalBitmap.UnlockBits(bitmapData);

                int width = originalBitmap.Width;
                int height = originalBitmap.Height;
                
                // 从四个方向分别扫描找到黑边边界
                int left = 0, top = 0, right = width - 1, bottom = height - 1;
                const int threshold = 50; // 黑色阈值
                
                // Windows 11 圆角处理参数
                int cornerRadius = Math.Min(width, height) / 20; // 估算圆角半径
                int minValidPixels = Math.Max(1, height / 10); // 每列/行至少需要的有效像素数

                // 从左边开始扫描 - 改进的算法，忽略可能的圆角区域
                bool foundLeft = false;
                for (int x = 0; x < width && !foundLeft; x++)
                {
                    int validPixelCount = 0;
                    for (int y = cornerRadius; y < height - cornerRadius; y++) // 跳过可能的圆角区域
                    {
                        int pixelIndex = y * stride + x * bytesPerPixel;
                        byte blue = rgbValues[pixelIndex];
                        byte green = rgbValues[pixelIndex + 1];
                        byte red = rgbValues[pixelIndex + 2];

                        if (red > threshold || green > threshold || blue > threshold)
                        {
                            validPixelCount++;
                        }
                    }
                    
                    // 如果这一列有足够多的非黑色像素，认为找到了左边界
                    if (validPixelCount >= minValidPixels)
                    {
                        left = x;
                        foundLeft = true;
                    }
                }

                // 从右边开始扫描 - 改进的算法
                bool foundRight = false;
                for (int x = width - 1; x >= left && !foundRight; x--)
                {
                    int validPixelCount = 0;
                    for (int y = cornerRadius; y < height - cornerRadius; y++) // 跳过可能的圆角区域
                    {
                        int pixelIndex = y * stride + x * bytesPerPixel;
                        byte blue = rgbValues[pixelIndex];
                        byte green = rgbValues[pixelIndex + 1];
                        byte red = rgbValues[pixelIndex + 2];

                        if (red > threshold || green > threshold || blue > threshold)
                        {
                            validPixelCount++;
                        }
                    }
                    
                    if (validPixelCount >= minValidPixels)
                    {
                        right = x;
                        foundRight = true;
                    }
                }

                // 从上边开始扫描 - 改进的算法
                bool foundTop = false;
                for (int y = 0; y < height && !foundTop; y++)
                {
                    int validPixelCount = 0;
                    for (int x = left + cornerRadius; x <= right - cornerRadius; x++) // 跳过可能的圆角区域
                    {
                        int pixelIndex = y * stride + x * bytesPerPixel;
                        byte blue = rgbValues[pixelIndex];
                        byte green = rgbValues[pixelIndex + 1];
                        byte red = rgbValues[pixelIndex + 2];

                        if (red > threshold || green > threshold || blue > threshold)
                        {
                            validPixelCount++;
                        }
                    }
                    
                    if (validPixelCount >= Math.Max(1, (right - left) / 10))
                    {
                        top = y;
                        foundTop = true;
                    }
                }

                // 从下边开始扫描 - 改进的算法
                bool foundBottom = false;
                for (int y = height - 1; y >= top && !foundBottom; y--)
                {
                    int validPixelCount = 0;
                    for (int x = left + cornerRadius; x <= right - cornerRadius; x++) // 跳过可能的圆角区域
                    {
                        int pixelIndex = y * stride + x * bytesPerPixel;
                        byte blue = rgbValues[pixelIndex];
                        byte green = rgbValues[pixelIndex + 1];
                        byte red = rgbValues[pixelIndex + 2];

                        if (red > threshold || green > threshold || blue > threshold)
                        {
                            validPixelCount++;
                        }
                    }
                    
                    if (validPixelCount >= Math.Max(1, (right - left) / 10))
                    {
                        bottom = y;
                        foundBottom = true;
                    }
                }

                // 如果没有找到非黑色区域或区域无效，返回原图
                if (!foundLeft || !foundRight || !foundTop || !foundBottom || 
                    right <= left || bottom <= top)
                {
                    return originalBitmap;
                }

                // 检查裁剪后的区域是否太小（可能是误判）
                int cropWidth = right - left + 1;
                int cropHeight = bottom - top + 1;
                
                // 如果裁剪后的区域小于原图的20%，可能是误判，返回原图
                if (cropWidth * cropHeight < (width * height * 0.2))
                {
                    return originalBitmap;
                }

                // 添加一些边距避免裁剪过度，但要考虑可能的圆角
                int leftMargin = Math.Min(2, left); // 如果left很小，说明可能没有黑边
                int topMargin = Math.Min(2, top);
                int rightMargin = Math.Min(2, width - 1 - right);
                int bottomMargin = Math.Min(2, height - 1 - bottom);
                
                left = Math.Max(0, left - leftMargin);
                top = Math.Max(0, top - topMargin);
                right = Math.Min(width - 1, right + rightMargin);
                bottom = Math.Min(height - 1, bottom + bottomMargin);

                // 裁剪图像
                Rectangle cropRect = new Rectangle(left, top, right - left + 1, bottom - top + 1);
                return originalBitmap.Clone(cropRect, originalBitmap.PixelFormat);
            }
            catch (Exception ex)
            {
                System.Windows.MessageBox.Show($"自动裁剪失败: {ex.Message}", "警告");
                return originalBitmap;
            }
        }

        public static void SaveScreenshot(Bitmap bitmap, string filePath)
        {
            try
            {
                string directory = Path.GetDirectoryName(filePath);
                if (!Directory.Exists(directory))
                {
                    Directory.CreateDirectory(directory);
                }

                bitmap.Save(filePath, ImageFormat.Png);
            }
            catch (Exception ex)
            {
                System.Windows.MessageBox.Show($"保存截图失败: {ex.Message}", "错误");
            }
        }
    }
}
